<template>
  <!-- 聊天记录 -->
  <div v-if="boxType=='multi'&&box.enable"
       :style="'z-index:'+box.zindex+';transform: translate('+box.x+'px, '+box.y+'px);width:'+box.width+'px;height:'+box.height+'px'+';background-color:'+box.backgroundColor+';opacity:'+box.opacity"
       class="chat-body">
    <div class="chatMian">
      <div class="chat">
        <el-scrollbar
            ref="chatRef"
            style="height: 100%;"
        >
          <div
              class="list"
              style="padding-bottom: 50px;"
              ref="chatListRef"
          >
            <div
                class="item"
                v-for="(item, index) in chatList"
                :key="index"
                :class="item.type == 'ask' ? 'ask' : 'reply'"
                ref="chatItemRef"
            >
              <div class="icon">
                <el-image
                  style="height: 40px;"
                  fit="contain"
                    v-if="item.type == 'ask' && userHeadVisible"
                    :src="userHead"
                />
                <el-image
                fit="contain"
                style="height: 40px;"
                    v-if="item.type == 'reply' && headVisible"
                    :src="aiHead"
                />
              </div>
              <div class="main">
                <div class="head" >
                  <div :style="'font-size: '+chatBoxFontSize+'px;'" v-show="false" class="left">
                    <span class="user">{{ item.type == 'ask' ? item.userName : '小薇' }}</span>
                    <span class="time">{{ item.createTime }}</span>
                  </div>
                  <div
                    v-show="false"
                      class="right"
                      v-if="item.type == 'reply'"
                  >
                    <i
                        class="el-icon-document-copy copy"
                        @click.stop="handleCopy(item)"
                    ></i>
                    <!-- <i
                      class="el-icon-top like"
                      @click.stop="handleLike(item)"
                    ></i>
                    <i
                      class="el-icon-bottom delike"
                      @click.stop="handleDelike(item)"
                    ></i> -->
                    <!-- <i
                      class="el-icon-refresh refresh"
                      @click.stop="handleRefresh(item)"
                    ></i> -->
                  </div>
                  <div class="thinkBack" v-if="item.showThink&&useThink">
                    <img style="width:12px;margin-right:5px" src="@/assets/images/thingking.png" alt="">
                    <span v-if="item.thinking" style="font-size: 12px;">正在思考...</span>
                    <span v-else-if="!item.thinking&&item.thinkContent&&item.thinkContent.length>0" style="font-size: 12px;">已深度思考</span>
                    <span v-else style="font-size: 12px;">已完成</span>
                  </div>
                </div>
                <div :style="'font-size: '+chatBoxFontSize+'px;'" class="text">
                  <span v-if="item.type == 'ask'">{{ item.askText }}</span>
                  <div
                      v-if="item.type == 'reply'"
                      class="typewriter"
                  >
                    <div class="thinkContent" v-if="item.thinkContent&&useThink" v-html="item.thinkContent">

                    </div>
                    <el-divider v-if="item.thinkContent&&useThink" />
                    <div v-html="item.replayContent">

                    </div>
                  </div>
                </div>
              </div>
            </div>

          </div>

          <!-- <div           v-if="showStopBtn"
                         style="width: 100%;display: flex;justify-content: center;align-items: center;height: 100%;">
            <div class=" unselectable"
                 style="position: absolute;bottom: 0px;height: 40px;color:#409eff;cursor: pointer;border:1px solid #409eff;border-radius: 20px;padding-top: 5px;padding-bottom: 5px;padding-left: 15px;padding-right: 15px;display: flex;justify-content: center;align-items: center;"
                 @click="handleStopReply"
            >
              <el-icon color="#409eff">
                <VideoPause/>
              </el-icon>
              停止回答
            </div>
          </div> -->

<!--          <el-button style="position: absolute;
          left: 0;
          right: 0;
          top: auto;
          bottom: 0;
          margin: auto;
          width: 15%;" @click="handleStopReply" 
          v-if="showStopBtn" 
          type="primary" plain round><el-icon><VideoPause /></el-icon>停止回答</el-button>-->

        </el-scrollbar>
        <!-- 停止按钮 -->
        <div v-show="showStopBtn&&stopBtnEnable" style="width: 100%;display: flex;justify-content: center;align-items: center;">
          <div @click="handleStopReply" class=""
                style="position: absolute;bottom: 0px;height: 40px;color:#409eff;cursor: pointer;border:1px solid #409eff;border-radius: 20px;padding-top: 5px;padding-bottom: 5px;padding-left: 15px;padding-right: 15px;display: flex;justify-content: center;align-items: center;">
            <el-icon color="#409eff">
              <VideoPause/>
            </el-icon>
            停止回答
          </div>
        </div>
        <!-- 添加打断词提示 -->
        <div v-if="showInterruptTip && voiceInterruptWord&&interruptTipEnalbe" style="width: 100%;display: flex;justify-content: center;align-items: center;">
          <div class="unselectable"
                style="position: absolute;bottom: -50px;height: 40px;color:#409eff;border:1px solid #409eff;border-radius: 20px;padding: 5px 15px;display: flex;justify-content: center;align-items: center;background-color: rgba(255, 255, 255, 0.9);white-space: nowrap;">
            <span>你可以说"{{ voiceInterruptWord }}"来打断</span>
          </div>
        </div>
      </div>
        
    </div>
  </div>
  <!-- 大屏回答 -->
  <div v-if="boxType=='single'&&box.enable"
       :style="'    border-radius: 30px;transform: translate('+box.x+'px, '+box.y+'px);width:'+box.width+'px;height:'+box.height+'px;'+'background-color:'+box.backgroundColor+';opacity:'+box.opacity"
       class="single-box chat-body">
    <div class="single-box__inner">
      <el-text v-if="chatList.length>0" style="color: #000;">{{ chatList[chatList.length - 1].replayContent }}</el-text>
    </div>
  </div>

  <!-- 问题 -->
  <div
  v-if="questions.enable"
   style="background-image: none;border: none"
       :style="'transform: translate('+questions.x+'px, '+questions.y+'px);width:'+questions.width+'px;height:'+questions.height+'px'"
       class="chat-body">
    <div style="padding: 0;justify-content: center;" class="chatMian">

      <div class="sub" >
        <div class="subFastInput" :style="';background-color:'+questions.backgroundColor+';opacity:'+questions.opacity">
          <!-- <el-button size="small" @click="submitFastAst(button)" round v-for="button in commonQuestions">{{
              button
            }}
          </el-button> -->
          <div @click="submitFastAst(button)" :style="'font-size: '+questionFontSize+'px;margin-right:5px;'" class="subFastInputBtn" :key="index" v-for="(button, index) in commonQuestions">
              {{
                button
              }}
            </div>
        </div>


      </div>
    </div>
  </div>

  <!-- 输入框 -->
  <div 
  v-if="input.enable&&platform != 'screen'"
  style="background-image: none;border: none"
       :style="'transform: translate('+input.x+'px, '+input.y+'px);width:'+input.width+'px;height:'+input.height+'px'"
       class="chat-body">
    <div style="padding: 0;justify-content: center;" class="chatMian">

      <div class="sub" >

        <div class="subInput" :style="'background-color:'+input.backgroundColor+';opacity:'+input.opacity">
          <div
              class="text el-textarea"
              v-show="!loading"
          >
            <div v-if="showRecordBtn" class="chat-input-box">
              <template v-if="getTheme === 'default'">
                <span @click="handleRecorder">

                <img v-if="!recording" src="@/assets/images/yuyin1.png" alt="">
                <img v-else src="@/assets/images/text.png" alt="">
                </span>
              </template>
              <template v-else>
                <span @click="handleRecorder">

                <img v-if="!recording" src="@/assets/images/yuyin-science.png" alt="">
                <img v-else src="@/assets/images/text-science.png" alt="">
                </span>
              </template>
            </div>

            <div class="chat-content-box">
              <!--                <div style="width: 100%;"> &lt;!&ndash; 波形绘制区域 &ndash;&gt;
                                <div style="display:inline-block;vertical-align:bottom">
                                  <div style="height:30px;width:300px;" ref="recwave"></div>
                                </div>
                              </div>-->
              <template v-if="!recording">
                <input @keydown.enter="inputKeydown" :style="{color: askTextColor}+';font-size:' +input.fontSize+'px'" ref="askTextRef" v-model="askText" type="text" placeholder="说点什么" autocomplete="off"></input>
              </template>
              <div style="height: 100%;display: flex;justify-content: center;" v-else>
                <img v-if="!isMute&&volume>0.4" style="height: 100%;" src="@/assets/images/voiceAnim.gif" alt="">
                <img v-if="!isMute&&volume<=0.4" style="height: 100%;" src="@/assets/images/voiceAnimNovoice.png" alt="">
                <img v-if="isMute" style="height: 100%;" src="@/assets/images/voiceAnimStop.png" alt="">
              </div>
            </div>
            <div class="chat-input-box">
                <span v-if="!recording" @click="submitAsk(false)">
<template v-if="getTheme === 'default'">

                <img src="@/assets/images/send.png" alt="">
                  </template>
                  <template v-else>
                                    <img src="@/assets/images/send-science.png" alt="">

                  </template>                </span>
              <template v-else>
                  <span v-if="!isMute" @click="toggleMute">
<template v-if="getTheme === 'default'">

                       <img src="@/assets/images/yinliang.png" alt="">
                    </template>
                    <template v-else>
                       <img src="@/assets/images/yinliang-science.png" alt="">
                    </template>                  </span>
                <span v-else @click="toggleMute">
<template v-if="getTheme === 'default'">

                    <img src="@/assets/images/mute.png" alt="">
                    </template>
                    <template v-else>

                    <img src="@/assets/images/mute-science.png" alt="">
                    </template>                  </span>
              </template>

            </div>

            <!-- <el-icon size="20" v-if="canRecord" @click="handleRecorder" :color="recording?'#ff0000':'#000'"><Microphone /></el-icon> -->
            <!--              <svg-icon class="btn" v-if="true" @click="handleRecorder" :name="!recording?'guanbiyuyin':'yuyin'" width="28px" height="20px"/>
                            <div style="padding-top:5px;position: absolute;left: 40px"> &lt;!&ndash; 波形绘制区域 &ndash;&gt;
                              <div style="display:inline-block;vertical-align:bottom">
                                <div style="height:30px;width:300px;" ref="recwave"></div>
                              </div>
                            </div>
                            <input

                              ref="askTextRef"
                              autocomplete="off"
                              v-model="askText"
                              placeholder="在这里输入提问"
                              class="el-textarea__inner"
                            />-->

            <!-- @keydown.ctrl.enter.exact="handleCtrlEnter" -->

            <!-- <span
              v-if="canRecord"
              class="el-icon-microphone-box"
              @click="handleRecorder"
            >
              <i :class="{ 'el-icon-microphone': true, 'recording': recording }"></i>
            </span> -->
          </div>
          <!-- <span
            class="btn"
            @click.stop="submitAsk(false)"
            v-show="!loading"
          >发 送</span> -->
          <!--              <svg-icon class="btn" @click.stop="submitAsk(false)" name="fasong" width="28px" height="20px"/>-->
          
          <!-- <div
              class="loading"
              v-show="loading"
              style="width: 100%;
              display: flex;
              justify-content: center;
              align-items: center;
              height: 100%;
              text-align: center;"
          >
            <el-text type="primary" style="font-size: 14px;">知识检索中...</el-text>
          </div> -->
        </div>

      </div>
    </div>
  </div>
</template>

<script>
import '@/styles/chat.scss';

import {getHtmlPlainText, initDate, isNull} from '@/util/common.js'
// import { chatFun, driveUeApi, asrApi } from '@/api/AiHumanWeb/AiHumanWebApi.js'
import {mittTypes} from '@/util/types';
import {getAudioToText} from "@/api/apiRequst"
// import Recorder from "js-audio-recorder";
//必须引入的核心
// import Recorder from 'recorder-core'

//引入mp3格式支持文件；如果需要多个格式支持，把这些格式的编码引擎js文件放到后面统统引入进来即可
// import 'recorder-core/src/engine/mp3'
// import 'recorder-core/src/engine/mp3-engine'
//录制wav格式的用这一句就行
// import 'recorder-core/src/engine/wav'

//可选的插件支持项，这个是波形可视化插件
// import 'recorder-core/src/extensions/frequency.histogram.view.js'
// import 'recorder-core/src/extensions/lib.fft.js'
import {getAssetsFile} from "@/util/common.js"
import { useSceneStore } from '@/stores/scene';
// import { platform } from 'os';

var _this;
export default {
  name: 'AiHumanWebIndex',
  props: {
    boxType: {
      type: String,
      default: 'Multi'
    },
    platform: {
      type: String,
      default: 'Web3d'
    },
    box: {
      type: Object,
      default: null
    },
    input: {
      type: Object,
      default: null
    },
    questions: {
      type: Object,
      default: null
    },
    commonQuestions: {
      type: Array,
      default: []
    },
  },
  data() {
    return {

      loading: false,
      askText: '',
      askTextColor: '#000',
      chatList: [],
      recorder: null,
      volume: null,
      showStopBtn: false,
      stopBtnEnable: true,
      showInterruptTip: false,
      interruptTipEnalbe: false,
      voiceInterruptWord: null,
      wave: null,
      recBlob: null,
      showRecordBtn: null,
      sessionId: '',
      recording: true,
      canRecord: false,
      isCtrlPressed: false, // 用于保存 Ctrl 键是否被按下
      getAssetsFile: getAssetsFile,
      currentItem: null,
      isMute: false,
      startMessage: true,
      questionFontSize: 15,
      chatBoxFontSize: 15,
      waitingWordTimeout: null,
      useThink: false,
      headVisible: true, // 数字人头像显示控制
      userHeadVisible: true, // 用户头像显示控制
      userHead:getAssetsFile('head_man.png'),
      aiHead:getAssetsFile('head_ai.png'),
      sceneStore:useSceneStore()
    };
  },
  computed: {
    getTheme() {
      return this.sceneStore.projectConfig.uiConfig.style.type
    }
  },  methods: {
    inputKeydown(e){
      
      if (e.keyCode == 13) {
         e.cancelBubble = true; //ie阻止冒泡行为
        e.stopPropagation();//Firefox阻止冒泡行为
        e.preventDefault(); //取消事件的默认动作*换行
        //以下处理发送消息代码
        // onSendMsg();
        this.submitAsk()
        // console.log(this.textarea);
      }
    },
    /**
     * 切换静音
     */
    toggleMute() {
      if (!this.isMute) {
        this.isMute = true;
        this.emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, false)
        // this.startRecorder();
      } else {
        // this.stopRecorder();
        this.isMute = false;
        this.emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
      }
    },
    handleEnter(event) {
      // if (!event.ctrlKey) {
      //   event.preventDefault();
      //   this.submitAsk();
      // }
      this.submitAsk();
    },
    // handleCtrlEnter(event) {
    //   if (event.ctrlKey) {
    //     this.askText += '\n';
    //   }
    // },
    submitFastAst(text) {
      this.loading = true;
      const createTime = new Date().getTime();
      const askItem = {
        id: createTime + '',
        type: 'ask',
        askText: text,
        createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
        userId: 'u1',
        userName: '我',
        userIcon: '/static/img/userIcon.png',
      };
      this.chatList.push(askItem);
      this.scrollToBottom();
      this.emitter.emit(mittTypes.LIVEKIT.MESSAGE_SEND, text)
      this.addLoadingReplyItem(null,true);
      this.emitter.emit(mittTypes.CHATBOX.UPDATE_USER_ACTIVE)
    },

    submitAsk(isFirst = false) {
      if (!isFirst && !this.askText) return;

      if(this.askText.startsWith('#')){//进入指令模式
        if(this.askText.includes('sleep')){//进入睡眠模式
          this.emitter.emit(mittTypes.SLEEPING_CONTROL.SLEEP);
         
        }else if(this.askText.includes('wakeup')){//唤醒模式
          this.emitter.emit(mittTypes.SLEEPING_CONTROL.WAKEUP);
          //发送唤醒消息
          // this.emitter.emit(mittTypes.LIVEKIT.WAKEUP_AGENT,true)
        }
        return;
      }

      this.loading = true;
      const createTime = new Date().getTime();
      const askItem = {
        id: createTime + '',
        type: 'ask',
        askText: this.askText,
        createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
        userId: 'u1',
        userName: '我',
        userIcon: '/static/img/userIcon.png',
      };
      if (!isFirst) {
        this.chatList.push(askItem);

        this.scrollToBottom();
      } else {
        this.sessionId = 'aihuman_web_' + new Date().getTime();
      }
      // const dataParams = {
      //   "askQuestion": this.askText,
      //   "projectId": this.projectId,
      //   "startAnew": isFirst ? "yes" : "no",
      //   "sendType": "2",
      //   "sessionId": this.sessionId,
      // }
      // chatFun(dataParams).then(res => {
      //   console.log(res);
      //   let replayContent = res.data.data.speech.ttsInfo.text || '';

      //   console.log(replayContent);
      //   const replyItem = {
      //     id: createTime + '',
      //     type: 'reply',
      //     replayContent: replayContent,
      //     createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
      //   };
      //   this.chatList.push(replyItem);
      //   this.scrollToBottom();

      //   this.driveUe(replayContent);

      // })
      this.emitter.emit(mittTypes.LIVEKIT.MESSAGE_SEND, this.askText)
      this.addLoadingReplyItem(null,true);
      this.emitter.emit(mittTypes.CHATBOX.UPDATE_USER_ACTIVE)
    },
    addLoadingReplyItem(message,think){
      _this.clearCurrentReply();
      const createTime = new Date().getTime();
      const replyItem = {
            id: createTime,
            type: 'reply',
            loading:true,
            showThink:think?true:false,
            thinking:think?true:false,
            replayContent: message?message:'意图识别中.',
            thinkContent: '',
            createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
          };
          _this.chatList.push(replyItem);
          _this.scrollToBottom();
          _this.handleChatReply();
          _this.currentItem = replyItem;
          _this.showStopBtn = true;
          _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_BUTTON,true)
          setTimeout(() => {
            if(_this.currentItem&&_this.currentItem.loading){
              _this.currentItem.replayContent = '意图识别中..'
              setTimeout(() => {
                if(_this.currentItem&&_this.currentItem.loading){
                  _this.currentItem.replayContent = '意图识别中...'
                }
              }, 1000);
            }
          }, 1000);
          _this.waitingWordTimeout = setTimeout(() => {
            if(_this.sceneStore.projectConfig.sleepConfig.waitingParams&&_this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode){
              if(typeof(_this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode)==Object){
                _this.emitter.emit(mittTypes.RENDERER.ADD_FLOWNODE,_this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode)
              }else if(Array.isArray(_this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode)&&_this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode.length>0){
                let random = Math.floor(Math.random() * _this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode.length);
                _this.emitter.emit(mittTypes.RENDERER.ADD_FLOWNODE,_this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode[random])
              }
            }
            
          }, 5000);
          _this.waitingWordLongTimeout = setTimeout(() => {
            if(_this.sceneStore.projectConfig.roleConfig.errorSpeech&&_this.sceneStore.projectConfig.roleConfig.errorSpeech.length>0){
              _this.emitter.emit(mittTypes.RENDERER.ADD_FLOWNODE,_this.sceneStore.projectConfig.sleepConfig.waitingParams.waitingFlowNode)
              let random = Math.floor(Math.random() * _this.sceneStore.projectConfig.roleConfig.errorSpeech.length);
              _this.emitter.emit(mittTypes.RENDERER.ADD_FLOWNODE,_this.sceneStore.projectConfig.roleConfig.errorSpeech[random])
            }
            
          }, 10000);
    },
    scrollToBottom() {
      this.$nextTick(() => {
        // this.$refs.chatRef.wrapRef.value.scrollTop = this.$refs.chatRef.wrapRef.value.scrollHeight;
        if(this.$refs.chatListRef){
          const max = this.$refs.chatListRef.clientHeight
          // console.log('max', max) // 如：当 count = 5 时，max = 总项数 * 每一项的高度 + 外边距 * (总项数 - 1)，即 max = 5 * 50px + 20px * (5 - 1) = 330px
          this.$refs.chatRef.setScrollTop(max)
        }
        // this.$refs.chatRef.scrollMenuRes.wrap.scrollTop=this.$refs.chatRef.scrollMenuRes.wrap.scrollHeight
      })
    },
    handleCopy(item) {
      // console.log('复制');
      this.$Clipboard({
        text: getHtmlPlainText(item.replayContent),
      }).then(() => {
        this.$message.success('复制成功')
      }).catch(() => {
        this.$message.error('复制失败')
      });
    },

    handleLike() {
      // console.log('点赞', item.id);
    },
    handleDelike() {
      // console.log('踩', item.id);
    },
    handleRefresh() {
      // console.log('刷新', item.id);
    },

    startTypewriter() {
      // console.log('startTypewriter');
      const lastRef = this.$refs.chatListRef.lastChild.lastChild.lastChild.lastChild;

      const text = lastRef.innerText;
      // console.log('lastRef', lastRef);
      let index = 0;
      lastRef.innerText = '';

      const typingInterval = setInterval(() => {
        lastRef.innerText += text[index];
        this.scrollToBottom();
        index++;
        if (index === text.length) {
          lastRef.className = "";
          clearInterval(typingInterval);
        }
      }, Math.floor(Math.random() * 40) + 40);
    },

    handleRecorder() {
      if (!this.recording) {
        this.recording = true;
        this.emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
      } else {
        this.recording = false;
        this.emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, false)
      }
    },

    startRecorder() {
      this.recording = true;
      if (!this.recorder) {
        console.error("未打开录音");
        this.$message.error("录音失败");
        this.recording = false;
        return
      }
      this.$message.success("开始录音");
      this.recorder.start()

      // console.log("已开始录音");

      // this.recorder.start().then(() => {
      //   console.log('开始录音');
      //   this.recording = true;
      //   this.$message.success("开始录音");
      // }, (error) => {
      //   // 出错了
      //   console.log(`${error.name} : ${error.message}`);
      //   this.recording = false;
      //   this.$message.error("录音失败");
      // });

    },

    stopRecorder() {
      console.log('停止录音');

      if (!this.recorder || this.recorder.duration === 0) {
        console.error("未打开录音");
        this.$message.error("未采集到声音");
        return
      }
      this.recorder.stop((blob, duration) => {
        //blob就是我们要的录音文件对象，可以上传，或者本地播放
        this.recBlob = blob;
        //简单利用URL生成本地文件地址，此地址只能本地使用，比如赋值给audio.src进行播放，赋值给a.href然后a.click()进行下载（a需提供download="xxx.mp3"属性）
        var localUrl = (window.URL || webkitURL).createObjectURL(blob);
        console.log("录音成功", blob, localUrl, "时长:" + duration + "ms");

        this.uploadRecord(blob);//把blob文件上传到服务器

        // this.recorder.close();//关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        // this.recorder=null;
        this.recording = false;
      }, (err) => {
        console.error("结束录音出错：" + err);
        this.recorder.close();//关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        this.recorder = null;
      });


      // this.recorder.stop();
      // this.recording = false;

      // if (this.recorder == null || this.recorder.duration === 0) {
      //   this.$message.error("未采集到声音");
      //   return false;
      // }

      // console.log(this.recorder.getPCMBlob());

      // let recordWAVBlob = this.recorder.getWAVBlob();

    },
    uploadRecord(blob) {
      const fileOfBlob = new File([blob], new Date().getTime() + ".wav");

      console.log(fileOfBlob);

      getAudioToText(fileOfBlob).then((res) => {
        console.log(res)
        if (res.status === 200 && !isNull(res.data.asr_msg)) {
          console.log(JSON.parse(res.data.asr_msg).alternatives[0].transcript)

          this.askText = JSON.parse(res.data.asr_msg).alternatives[0].transcript;
          this.submitAsk();

        } else {
          this.askText = '';
        }
      })
    },

    transformToUe(dataParams) {
      console.log('transformToUe', dataParams);
    },

    // async driveUe(dataParams) {

    //   /*女生出场*/
    //   const startData = {
    //     "type": 7,
    //     "data": {
    //       "speech": {
    //         "genType": "2",
    //         "ttsInfo": {
    //           "text": dataParams,
    //           "ssml": "<speak xmlns=\"http://www.w3.org/2001/10/synthesis\" version=\"1.0\" xml:lang=\"zh-CN\"><voice name=\"zh-CN-XiaoxiaoNeural\"  xml:gender=\"male\" xml:lang=\"zh-CN\"><prosody rate=\"1\" volum=\"100\">" + dataParams + "</prosody></voice></speak>"
    //         }
    //       },
    //       "modelActions": [
    //         {
    //           "actionId": "Idle_2",
    //           "startTime": "00:00:01:000",
    //           "endTime": "00:00:00:000",
    //         },
    //         {
    //           "actionId": "F-52",
    //           "startTime": "00:00:03:000",
    //           "endTime": "00:00:00:000",
    //         },
    //         {
    //           "actionId": "F-83",
    //           "startTime": "00:00:10:000",
    //           "endTime": "00:00:00:000",
    //         },
    //         {
    //           "actionId": "F-95",
    //           "startTime": "00:00:18:000",
    //           "endTime": "00:00:00:000",
    //         },
    //         {
    //           "actionId": "F-50",
    //           "startTime": "00:00:24:000",
    //           "endTime": "00:00:00:000",
    //         },
    //         {
    //           "actionId": "Idle_3",
    //           "startTime": "00:00:29:000",
    //           "endTime": "00:00:00:000",
    //         },
    //       ],
    //       "nodeTime": 31
    //     }
    //   }

    //   if (window.AiHumanPMSDK.AiHumanIsReady) {
    //     await driveUeApi(startData).then((res) => {
    //       console.log('res', res);
    //       this.handleChatReply();
    //     });
    //   } else {
    //     this.handleChatReply();
    //   }
    // },
    handleStopReply(){
      _this.clearCurrentReply()
      this.emitter.emit(mittTypes.WEBHUMAN.STOP_VISEME_AUDIO)
      this.emitter.emit(mittTypes.LIVEKIT.INTERRUPT)
      this.emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
      this.emitter.emit(mittTypes.CHATBOX.UPDATE_USER_ACTIVE,true)
      if(_this.currentItem){
        _this.currentItem.replayContent+='<span style="color:#ccc">(此条回复已被打断)</span>'
      }
      _this.currentItem = null
      _this.showStopBtn = false
      _this.showInterruptTip = false;
      _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_BUTTON,false)
      _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_TIP,false)
    },
    clearCurrentReply(){
      if(_this.currentItem&&_this.currentItem.loading){
        _this.chatList.forEach((element,index) => {
          if(element.replayContent == '意图识别中...'||element.replayContent == '意图识别中.'||element.replayContent == '意图识别中..'){
            _this.chatList.splice(index,1)
          }
          
        });
        _this.currentItem = null
      }
      
    },

    handleChatReply() {
      this.loading = false;
      this.askText = '';
      this.$nextTick(() => {
        if(_this.$refs.askTextRef){
          _this.$refs.askTextRef.focus();
        }
        
        // this.startTypewriter();
      })
    },

    checkRecordingSupport() {
      this.recorder.open(() => {
        console.log("录音已打开");
        this.$message.success("获取麦克风权限成功");
        this.canRecord = true;
        if (this.$refs.recwave) {//创建音频可视化图形绘制对象
          this.wave = Recorder.FrequencyHistogramView({
            elem: this.$refs.recwave
            , height: 30
            , lineCount: 30
            , widthRatio: 0.6
            , position: 0
            , minHeight: 1
            , fallDuration: 400
            , stripeEnable: false
            , mirrorEnable: true
            , linear: [0, "#4ebbfa", 1, "#62e2f6"]
            , fullFreq: false
          });
        }
      }, (msg, isUserNotAllow) => {
        //用户拒绝了录音权限，或者浏览器不支持录音
        console.log((isUserNotAllow ? "UserNotAllow，" : "") + "无法录音:" + msg);
        this.$message.error("获取麦克风权限成功失败");
        this.canRecord = false;
      });
      // Recorder.getPermission().then(() => {
      //   this.$message.success("获取麦克风权限成功");
      //   this.canRecord = true;
      // }, (error) => {
      //   console.log(`${error.name} : ${error.message}`);
      //   this.$message.error("获取麦克风权限成功失败");
      //   this.canRecord = false;
      // });

    },

    handleKeyDown(event) {
      if (event.ctrlKey) {
        this.isCtrlPressed = true;
        if (!this.recording) {
          this.startRecorder();
        }
      }

      if (event.key === 'Enter') {
        this.submitAsk();
      }
    },
    handleKeyUp(event) {
      if (!event.ctrlKey) {
        this.isCtrlPressed = false;
        if (this.recording) {
          this.stopRecorder();
        }
      }
    },
    clearWaitingWordTimeout(){
      if(_this.waitingWordTimeout){
              clearTimeout(_this.waitingWordTimeout)
              _this.waitingWordTimeout = null;
            }
      if(_this.waitingWordLongTimeout){
              clearTimeout(_this.waitingWordLongTimeout)
              _this.waitingWordLongTimeout = null;
            }
    }
  },
  mounted() {
    // if(this.x>0){
    //   this.left = x;
    //   this.right = 0;
    // }else if(this.x<0){
    //   this.left = 0;
    //   this.right = x;
    // }else{
    //   this.left = 0;
    //   this.right = 0;
    // }

    // this.projectId = '1739858616928337921';
    // this.submitAsk(true);


    // this.recorder = Recorder({
    // 	type:"wav" //录音格式，可以换成wav等其他格式
    // 	,sampleRate:16000 //录音的采样率，越大细节越丰富越细腻
    // 	,bitRate:16 //录音的比特率，越大音质越好
    // 	,onProcess:(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd)=>{
    // 		//录音实时回调，大约1秒调用12次本回调
    // 		//可实时绘制波形，实时上传（发送）数据
    // 		if(this.wave) this.wave.input(buffers[buffers.length-1],powerLevel,bufferSampleRate);
    // 	}
    // });

    // this.checkRecordingSupport();

    // this.recorder.onprogress = (params) => {
    //   // console.log('录音时长(秒)', params.duration);
    //   this.askText = parseFloat(params.duration.toFixed(3)) + '秒';
    //   // console.log('录音大小(字节)', params.fileSize);
    //   // console.log('录音音量百分比(%)', params.vol);
    //   // console.log('当前录音的总数据([DataView, DataView...])', params.data);
    // };

    // 监听 keydown 事件
    // window.addEventListener('keydown', this.handleKeyDown);
    // 监听 keyup 事件
    // window.addEventListener('keyup', this.handleKeyUp);
    _this = this;
    if(_this.sceneStore.projectConfig.uiConfig.chatbox.questions.fontSize){
      _this.questionFontSize = _this.sceneStore.projectConfig.uiConfig.chatbox.questions.fontSize
    }
    if(_this.sceneStore.projectConfig.uiConfig.chatbox.box.fontSize){
      _this.chatBoxFontSize = _this.sceneStore.projectConfig.uiConfig.chatbox.box.fontSize
    }
    if(_this.sceneStore.projectConfig.uiConfig.interrupt){
      _this.stopBtnEnable = _this.sceneStore.projectConfig.uiConfig.interrupt.buttonInterrupt
    }
    if(_this.sceneStore.projectConfig.uiConfig.interrupt){
      _this.interruptTipEnalbe = _this.sceneStore.projectConfig.uiConfig.interrupt.tip
    }
    _this.useThink = _this.sceneStore.projectConfig.uiConfig.chatbox.box.useThink
    if(_this.sceneStore.projectConfig.createRoomParam){
      if(_this.sceneStore.projectConfig.createRoomParam.llmConfig.MODEL_NAME.indexOf('DeepSeek-R1')>-1){
        _this.useThink = true;
      }
    }
    // 初始化打断词
    if(_this.sceneStore.projectConfig.uiConfig.interrupt.voiceInterruptWords&&_this.sceneStore.projectConfig.uiConfig.interrupt.voiceInterruptWords.length>0){
      _this.voiceInterruptWord = _this.sceneStore.projectConfig.uiConfig.interrupt.voiceInterruptWords[0]
    }
    const createTime = new Date().getTime();
    
    switch(_this.sceneStore.projectConfig.uiConfig.chatbox.input.type){
        case 'audio':
        _this.showRecordBtn = false
        _this.recording = true
          break;
        case 'text':
        _this.showRecordBtn = false
        _this.recording = false
        // _this.emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, false)
          break;
        case 'audioText':
        _this.showRecordBtn = true
        _this.recording = true
          break;
      }

    this.emitter.on(mittTypes.LIVEKIT.AUDIO_ENABLE, function(value){
      _this.isMute = !value
    })
    this.emitter.on(mittTypes.LIVEKIT.MESSAGE_CHAT_RECIVE, function (data) {
      let messageData = data.messageData;
      let from = data.from;
      switch (from) {
        case mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.BOT:
          if (messageData.message.indexOf('<|STT|>') >= 0) {
            return
          }
          // const replyItem = {
          //   id: messageData.id,
          //   type: 'reply',
          //   replayContent: messageData.message,
          //   createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
          // };
          // _this.chatList.push(replyItem);
          // _this.scrollToBottom();
          // _this.handleChatReply();
          // _this.currentItem = replyItem;
          _this.showStopBtn = true;
          if (_this.currentItem) {
            if(_this.currentItem.loading){
              _this.currentItem.replayContent = ''
              _this.currentItem.loading = false
            }
            _this.currentItem.thinking = false
            _this.currentItem.replayContent += messageData.message
            _this.currentItem.id = messageData.id
            _this.clearWaitingWordTimeout()
            // 添加打断词提示逻辑
            if (_this.currentItem.replayContent.length > 100 && _this.voiceInterruptWord&&! _this.showInterruptTip) {
              _this.showInterruptTip = true;
              _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_TIP,true)
              // 5秒后自动隐藏
              setTimeout(() => {
                _this.showInterruptTip = false;
                _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_TIP,false)
              }, 5000);
            }
          }
          // else if(_this.startMessage){
          //   _this.startMessage = false;
          //   _this.addLoadingReplyItem(messageData.message)
          //   _this.currentItem = null;
            // _this.showStopBtn = false;
          // }
          break;
        case mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.LOCAL:
          // 用户asr结果
          const asrItem = {
            id: messageData.id,
            type: 'ask',
            askText: messageData.message,
            createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
            userId: 'u1',
            userName: '我',
            userIcon: '/static/img/userIcon.png',
          };
          _this.chatList.push(asrItem);
          _this.scrollToBottom();
          if(!data.wakeOrsleepWord){
            _this.addLoadingReplyItem(null,true);
          }
          
          _this.handleChatReply();

          break;
      }

    })
    let timeout
    this.emitter.on(mittTypes.RENDERER.FLOWNODE_LIST_END,function(){
      _this.showStopBtn = false;
      // _this.showInterruptTip = false;
      _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_BUTTON,false)
      // _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_TIP,false)
    })
    this.emitter.on(mittTypes.CHATBOX.ADD_WAITING_MESSAGE,function(){
      _this.addLoadingReplyItem(null,true);
    })
    this.emitter.on(mittTypes.CHATBOX.STOP_REPLY,function(){
      _this.handleStopReply();
    })
    this.emitter.on(mittTypes.CHATBOX.CLEAR_WAITING_TIMEOUT,function(){
      _this.clearWaitingWordTimeout();
    })
    this.emitter.on(mittTypes.CHATBOX.ADD_MESSAGE,function(message){
      _this.addLoadingReplyItem(null,true);
      if (_this.currentItem ) {
        _this.currentItem.replayContent = message
        _this.currentItem.loading = false
        _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_BUTTON,true)
        _this.scrollToBottom();
        _this.clearWaitingWordTimeout()
      }
    })
    this.emitter.on(mittTypes.CHATBOX.ADD_THINK_MESSAGE,function(thinkMessage){
      // _this.addLoadingReplyItem(null,thinkMessage);
      if (_this.currentItem ) {
        _this.currentItem.thinkContent = thinkMessage
        // _this.currentItem.loading = false
        _this.currentItem.thinking = true
        _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_BUTTON,true)
        _this.scrollToBottom();
        _this.clearWaitingWordTimeout()
      }
    })
    this.emitter.on(mittTypes.LIVEKIT.MESSAGE_CHAT_UPDATE, function (data) {
      let messageData = data.messageData;
      let from = data.from;
      switch (from) {
        case mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.BOT:
          // const replyItem = {
          //   id: createTime + '',
          //   type: 'reply',
          //   replayContent: messageData.message,
          //   createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
          // };
          if (messageData.message.indexOf('<|STT|>') >= 0) {
            return
          }
          if (_this.currentItem && _this.currentItem.id == messageData.id) {
            _this.currentItem.replayContent = messageData.message
            _this.currentItem.loading = false
            _this.currentItem.thinking = false
            _this.showStopBtn = true;
            _this.emitter.emit(mittTypes.RENDERER.SET_SHOW_INTERRUPT_BUTTON,true)
            clearTimeout(timeout)
            // timeout = setTimeout(() => {
            //   _this.showStopBtn = false;
            // }, 2000);
            _this.scrollToBottom();
            _this.clearWaitingWordTimeout()
          }
          
          
          
          // _this.chatList.push(replyItem);
          
          // _this.handleChatReply();
          break;
        case mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.LOCAL:
          // 用户asr结果
          _this.emitter.emit(mittTypes.CHATBOX.UPDATE_USER_ACTIVE)
          if (messageData.message.indexOf('<|STT|>') >= 0) {
            return
          }
          const asrItem = {
            id: createTime + '',
            type: 'ask',
            askText: messageData.message,
            createTime: initDate(createTime, 'MM-dd HH:mm:ss'),
            userId: 'u1',
            userName: '我',
            userIcon: '/static/img/userIcon.png',
          };
          _this.chatList.push(asrItem);
          _this.scrollToBottom();
          _this.handleChatReply();
          break;
      }

    })
    // this.handleChatReply();

    if(this.sceneStore.projectConfig.uiConfig.style.type == "scientific"){
      this.userHead = getAssetsFile('style/scientific/head_man.png')
      this.aiHead = getAssetsFile('style/scientific/head_ai.png')
      this.askTextColor = '#ffffff'
    }else{
      this.userHead = getAssetsFile('head_man.png')
      this.aiHead = getAssetsFile('head_ai.png')
      this.askTextColor = '#000000'
    }
    if(_this.sceneStore.projectConfig.uiConfig.chatbox.box.headImg&&_this.sceneStore.projectConfig.uiConfig.chatbox.box.headImg!=''&&_this.sceneStore.projectConfig.uiConfig.chatbox.box.headImg!='default'){
      _this.aiHead = _this.origin+_this.sceneStore.projectConfig.uiConfig.chatbox.box.headImg
    }
    if(_this.sceneStore.projectConfig.uiConfig.chatbox.box.userHeadImg&&_this.sceneStore.projectConfig.uiConfig.chatbox.box.userHeadImg!=''&&_this.sceneStore.projectConfig.uiConfig.chatbox.box.userHeadImg!='default'){
      _this.userHead = _this.origin+_this.sceneStore.projectConfig.uiConfig.chatbox.box.userHeadImg
    }
    // 初始化头像显示状态
    if (_this.sceneStore.projectConfig.uiConfig.chatbox.box.headVisible !== undefined) {
      _this.headVisible = _this.sceneStore.projectConfig.uiConfig.chatbox.box.headVisible;
    }
    if (_this.sceneStore.projectConfig.uiConfig.chatbox.box.userHeadVisible !== undefined) {
      _this.userHeadVisible = _this.sceneStore.projectConfig.uiConfig.chatbox.box.userHeadVisible;
    }

    this.emitter.on(mittTypes.SLEEPING_CONTROL.ON_SLEEP_START,function(){
      if(_this.$refs.askTextRef){
        _this.$refs.askTextRef.blur();
      }
      
    })
    this.emitter.on(mittTypes.CHATBOX.UPDATE_CHATBOX_VOLUME,function(volume){
      _this.volume = volume
      
    })
  },
  beforeDestroy() {
    // 在组件销毁前移除事件监听器
    window.removeEventListener('keydown', this.handleKeyDown);
    window.removeEventListener('keyup', this.handleKeyUp);
  },

};
</script>
<style lang="scss">
.chat-content-box {
  flex: 1;
  height: 40px;

  input {
    background: transparent;
    border: none;
    outline: none;
    color: #999;
    font-size: 14px;
    height: 100%;
    width: 100%;
  }
}

.chat-input-box {
  width: 6%;
  display: flex;
  align-items: center;
  justify-content: center;

  span {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  img {
    cursor: pointer;
    height: 45px;
    width: 100%;
    object-fit: contain;
  }
}
.single-box {
  padding: 4px;
  border-radius: 30px;
  background: linear-gradient(to bottom, #C786FF, #4883FF);

  &__inner {
    display: flex;
    background: linear-gradient(-15deg, #CDE2F9 0%, #E5E2FF 100%);
    border-radius: 30px;
    height: 100%;
    width: 100%;
    text-align: center;
    padding: 20px;
  }
}

.chat-body {
  position: absolute;
  //background-image: linear-gradient(to right,  #eeeff5,#cde2f9 );
  top: 0px;
  left: 0px;
  bottom: 0;
  right: 0;
  margin: auto;
  // z-index: 1000;
  border-radius: 5px;
  padding: 5px;
  // box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
  // border: 2px #fff solid;
  .typewriter {
    // &::after {
    //   content: "|";
    //   display: inline-block;
    //   animation: blink-caret 0.5s infinite;
    // }
  }

  .el-textarea {
    display: flex;
    align-items: center;
  }

  .recording {
    color: #ff0000;
  }

  .el-icon-microphone-box {
    height: 120%;
    width: 60px;
    display: flex;
    align-items: center;
    justify-content: center;

    .el-icon-microphone {
      font-size: 32px;
      cursor: pointer;
    }
  }
}
.thinkContent{
  color: #737986;
  padding-left: 5px;
  border-left: 1px solid #C0CADE;
}
.thinkBack{
  border-radius: 5px;
  background-color: #ffffff77;
  padding: 5px;
}
</style>
  